<script>
import service from '@/utils/request'

const QueryEmit = 'query'

export default {
  name: 'SelectionTemplate',
  model: {
    event: 'input',
    prop: 'value'
  },
  props: {
    title: {
      type: String,
      default: '选择数据'
    },
    mode: {
      type: String,
      default: 'input'
    },
    value: {
      type: String,
      default: null
    },
    names: {
      type: String,
      default: null
    },
    dataset: {
      type: String,
      default: null
    },
    isRowModel: {
      type: Boolean,
      default: false
    },
    dataListUrl: {
      type: String,
      default: ''
    },
    deleteUrl: {
      type: String,
      default: ''
    },
    isPage: {
      type: Boolean,
      default: true
    },
    createdIsNeed: {
      type: Boolean,
      default: true
    },
    primaryKey: {
      type: String,
      default: 'id'
    },
    exportUrl: {
      type: String,
      default: ''
    },
    isOperate: {
      type: Boolean,
      default: true
    },
    isOperateBtn: {
      type: Boolean,
      default: true
    },
    textAlign: {
      type: String,
      default: 'right'
    },
    isTable: {
      type: Boolean,
      default: true
    },
    isPageHelper: {
      type: Boolean,
      default: true
    },
    multiple: {
      type: Boolean,
      default: false
    },
    showFormat: {
      type: String,
      default: 'value'
    },
    nameKey: {
      type: String,
      default: 'name'
    }
  },
  data() {
    return {
      selections: [],
      visible: false,
      params: {},
      dataList: [],
      dataListLoading: false,
      queryForm: {
        code: ''
      },
      order: '',
      asc: false,
      page: 1,
      limit: 10,
      total: 0,
      pageSizes: [10, 20, 50, 100, 200],
      dataListSelections: []
    }
  },
  watch: {
    value: {
      handler() {
        this.parserValue()
      }
    }
  },
  created() {
    this.query()
  },
  methods: {
    parserInputFormat() {
      if (this.showFormat === 'value') {
        return this.selections.map(item => item[this.primaryKey]).join(',')
      }
      if (this.showFormat === 'name') {
        return this.selections.map(item => item[this.nameKey]).join(',')
      }
      return this.selections.map(item => this.parserDataset(item)).join(',')
    },
    setQueryParams(prop, value) {
      this.queryForm[prop] = value
    },
    addOrUpdateHandle(id, item) {
      this.$emit('edit', id, item)
    },
    created() {
      this.$emit('created')
      if (this.createCallback !== null &&
        typeof this.createCallback === 'function') {
        this.createCallback()
      }
    },
    query() {
      if (this.queryCallback !== null &&
        this.queryCallback !== undefined &&
        typeof this.queryCallback === 'function') {
        return this.createCallback(this)
      }

      if (!this.dataListUrl) {
        return
      }
      this.$emit(QueryEmit, this.queryForm, this)
      this.dataListLoading = true

      service
        .get(this.dataListUrl, {
          params: {
            order: this.order,
            asc: this.asc,
            page: this.isPage ? this.page : null,
            limit: this.isPage ? this.limit : null,
            ...this.queryForm
          }
        })
        .then((res) => {
          this.dataList = this.isPage ? res.data.list : res.data
          this.total = this.isPage ? res.data.total : 0
          this.dataList.forEach(e => {
            e.check = false
          })
        })

      this.dataListLoading = false
    },
    getDataList() {
      this.page = 1
      this.query()
    },
    deleteHandle(key) {
      if (!this.deleteUrl) {
        return
      }
      this.$msgbox.confirm('确定进行删除操作?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          service.delete(this.deleteUrl + '/' + key).then(() => {
            this.$message.success('删除成功')

            this.query()
          })
        })
        .catch(() => {
        })
    },
    deleteBatchHandle(key) {
      let data = []
      if (key) {
        data = [key]
      } else {
        data = this.dataListSelections ? this.dataListSelections : []

        if (data.length === 0) {
          this.$message.warning('请选择删除记录')
          return
        }
      }

      this.$msgbox.confirm('确定进行删除操作?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          if (this.deleteUrl) {
            service.delete(this.deleteUrl, { data }).then(() => {
              this.$message.success('删除成功')

              this.query()
            })
          }
        })
        .catch(() => {
        })
    },
    selectionChangeHandle(selections) {
      this.dataListSelections = selections.map((item) =>
        this.primaryKey && item[this.primaryKey])
    },
    sizeChangeHandle(val) {
      this.page = 1
      this.limit = val
      this.query()
    },
    currentChangeHandle(val) {
      this.page = val
      this.query()
    },
    sortChangeHandle(val) {
      const { prop, order } = val
      if (prop && order) {
        this.order = prop
        this.asc = order === 'ascending'
      } else {
        this.order = ''
      }
      this.query()
    },
    onSingleCheck(row) {
      this.selections = [row]
      this.dataListSelections = [row]
      this.updateValues()
      this.parserInputFormat()
      this.visible = false
    },
    updateValues() {
      this.$emit('input', this.selections.map(e => e[this.primaryKey]).join(','))
      this.$emit('update:names', this.selections.map(e => e[this.nameKey]).join(','))
      this.$emit('update:dataset', this.selections.map(e => this.parserDataset(e)).join(','))
    },
    parserDataset(e) {
      return this.nameKey + '=' + e[this.names] +
        ':' + this.primaryKey + '=' + e[this.primaryKey]
    },
    parserValue() {
      this.dataListSelections = []
      this.selections = []
      if (this.value && this.dataset &&
        this.value.split(',').length ===
        this.dataset.split(',').length) {
        this.dataset.split(',').map(e => {
          const obj = {}
          e.split(':').forEach(prop => {
            const mate = prop.split('=')
            obj[mate[0]] = mate[1]
          })
          this.selections.push(obj)
          this.dataListSelections.push(obj)
        })
      } else if (this.value && this.names &&
        this.value.split(',').length === this.names.split(',').length) {
        const values = this.value.split(',')
        const names = this.names.split(',')
        for (let i = 0; i < values.length; i++) {
          const obj = {}
          obj[this.nameKey] = names[i]
          obj[this.primaryKey] = values[i]
          this.selections.push(obj)
          this.dataListSelections.push(obj)
        }
      } else {
        const values = (this.value || '').split(',')
        if (this.value === '') {
          return
        }
        for (let i = 0; i < values.length; i++) {
          const obj = {}
          obj[this.primaryKey] = values[i]
          obj[this.nameKey] = values[i]
          this.selections.push(obj)
          this.dataListSelections.push(obj)
        }
      }
    },
    onClick() {
      this.visible = true
      this.query()
    },
    reset() {
      this.page = 1
      this.query()
    }
  }
}
</script>

<template>
  <div>
    <template v-if="mode === 'input'">
      <el-input v-bind="$attrs" :readonly="true" :value="parserInputFormat()">
        <template #append>
          <el-button v-bind="$attrs" @click="onClick">选择</el-button>
        </template>
      </el-input>
    </template>
    <el-dialog :visible.sync="visible" modal-append-to-body width="70%" :title="title">
      <el-form :model="params" size="small" inline>
        <slot name="query" :param="queryForm" :query="query" :reset="reset" />
      </el-form>
      <el-table
        v-loading="dataListLoading"
        :data="dataList"
        border
        size="small"
        v-bind="$attrs"
        height="50vh"
        :row-key="primaryKey"
        style="width: 100%;"
        v-on="$listeners"
        @select="selectionChangeHandle"
      >
        <el-table-column v-if="multiple" type="selection" :reserve-selection="true" width="50" align="center" />
        <el-table-column v-else width="55" align="center">
          <template #default="{row}">
            <el-checkbox v-model="row.check" @change="onSingleCheck(row)" />
          </template>
        </el-table-column>
        <slot />
      </el-table>
      <el-row style="margin-top: 10px">
        <el-col :span="4">
          <el-button size="small">
            确定
          </el-button>
        </el-col>
        <el-col :span="20" style="text-align: right">
          <el-pagination
            :current-page="page"
            :page-sizes="pageSizes"
            :page-size="limit"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="sizeChangeHandle"
            @current-change="currentChangeHandle"
          />
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
::v-deep .el-dialog__body {
  padding: 10px 10px;
}

::v-deep .el-dialog__header {
  padding: 10px 10px 5px;
  border-bottom: 1px solid #F2F6FC;
  font-size: 12px;
}

::v-deep .el-form-item {
  margin-bottom: 10px;
}
</style>
